/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.edmo.fastener.business;

import com.edmo.fastener.dao.CustomerOrderDao;
import com.edmo.fastener.domain.Customer;
import com.edmo.fastener.domain.CustomerOrder;
import com.edmo.fastener.domain.Order;
import com.edmo.fastener.domain.OrderItem;
import com.edmo.fastener.domain.Supplier;
import com.edmo.fastener.parser.ParseOrder;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @author obelog
 */
public class OrderProcessing implements Runnable {

    private static Logger log = LoggerFactory.getLogger(OrderProcessing.class);
    private List<Order> orders;
    private String path;
    private String fileName;
    private int discount;
    private int dalivday;
    private Supplier supplier;
    private Customer customer;
    private Long orderID;// = ListofCustomersnSuppliers.getOrderId();
    
    public OrderProcessing(String path, String fileName, Long orderID) {
        this.fileName = fileName;
        this.path = path;
        this.orderID = orderID;
    }

    public void processing() {
        orders = new ParseOrder().readnParse(path);
        getCustomerState();
        remane(String.valueOf(orderID));
        //path = "order\\CUSTOMERS\\C70\\order1.ord"; //remove IT!!!!
        findTheSameOrders();
        findSupplier();
        SaveSupplierOrderDB();
        //System.out.println("---Time" + orderID + "--- " + System.currentTimeMillis());
    }
    
    private void SaveSupplierOrderDB(){
        CustomerOrder cos = new CustomerOrder(customer.getCustomerName(), customer.getState());
        cos.setId(orderID);
        
        

        for (int i = 0; i < orders.size(); i++) {
            String buf = "";
            OrderItem o1 = new OrderItem();
            cos.getOrderItem().add(o1);
            o1.setSuk(String.valueOf(orders.get(i).getSuk()));
            o1.setPcs(String.valueOf(orders.get(i).getPcs()));
            o1.setMaterial(orders.get(i).getMaterial());
            o1.setDelivery(orders.get(i).getDeliv());
            if (orders.get(i).getSupplier() != null){
               o1.setSupplierCode(orders.get(i).getSupplier().getSupplierCode()); 
            }
            
            o1.setCustomerOrder(cos);
            buf += o1.toString() + "\n";
            if (orders.get(i).getSupplier() != null){
                writeOrdertoFile(String.valueOf(orderID), buf, orders.get(i).getSupplier().getSupplierCode());
            }
        }
    
        saveOrderDB(cos);
    }
    
    private void saveOrderDB(CustomerOrder cos) {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"aplication-context.xml"});
        CustomerOrderDao customerOrderDao = (CustomerOrderDao) context.getBean("customerOrderDao");
        customerOrderDao.save(cos); 
        System.out.println("---Save--- " + orderID + " " + System.currentTimeMillis());
//        SaverToDB sdb = ListofCustomersnSuppliers.getSaverToDB();
//       (sdb.getList()).add(cos);
    }
    
    private void writeOrdertoFile(String id, String data, String supCode) {
        log.info("writeOrdertoFile ");
        String file = path.replace(fileName.replace(".txt", "") + ".ord", getDate() + "-" + id + ".txt");
        file = file.replace("CUSTOMERS", "SUPPLIERS");
        file = file.replace(customer.getCustomerName(), supCode);
        try {
            FileWriter fstream = new FileWriter(file, true);
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(data);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void findSupplier() {
        String customerState = customer.getState();
        List<Supplier> nativeStates = new ArrayList<Supplier>();
        for (Supplier list : ListofCustomersnSuppliers.getSuppliers()) {
            if (list.getState().equals(customerState)) {
                nativeStates.add(list);
            }
        }
        if (nativeStates.isEmpty()) {
            orderRejected();
        }
        for (int i = 0; i < orders.size(); i++) {
            supplier = null;
            dalivday = -1;
            discount = -1;
            for (Supplier list : nativeStates) {
                String[] range = list.getRange().split("-");
                int r1 = (int) Integer.valueOf(range[0]);
                int r2 = (int) Integer.valueOf(range[1]);
                int suk = (int) Integer.valueOf(orders.get(i).getSuk());
                if (suk >= r1 && suk <= r2 && orders.get(i).getMaterial().equals(list.getMaterial())) {
                    if (orders.get(i).getDeliv().equals("P")) {
                        bestPrice(list);
                    }
                    if (orders.get(i).getDeliv().equals("D")) {
                        bestDelivery(list);
                    }
                }
                orders.get(i).setSupplier(supplier);
            }
            if (supplier == null) {
                partRejected(orders.get(i));
            }
        }
    }

    public void setSupplier(String supplier) {
        int sup = Integer.valueOf(supplier.replace("S_00", ""));
        this.supplier = ListofCustomersnSuppliers.getSuppliers().get(sup - 1);
    }

    private void bestPrice(Supplier list) {
        if (discount == -1) {
            discount = list.getDiscount();
            dalivday = list.getDelivry();
            setSupplier(list.getSupplierCode());
        }
        if (discount < list.getDiscount()) {
            discount = list.getDiscount();
            dalivday = list.getDelivry();
            setSupplier(list.getSupplierCode());
        }
        if (discount == list.getDiscount() && dalivday > list.getDelivry()) {
            discount = list.getDiscount();
            dalivday = list.getDelivry();
            setSupplier(list.getSupplierCode());
        }
    }

    private void bestDelivery(Supplier list) {
        if (dalivday == -1) {
            discount = list.getDiscount();
            dalivday = list.getDelivry();
            setSupplier(list.getSupplierCode());
        }
        if (dalivday > list.getDelivry()) {
            discount = list.getDiscount();
            dalivday = list.getDelivry();
            setSupplier(list.getSupplierCode());
        }
        if (dalivday == list.getDelivry() && discount < list.getDiscount()) {
            discount = list.getDiscount();
            dalivday = list.getDelivry();
            setSupplier(list.getSupplierCode());
        }
    }

    private void partRejected(Order order) {
        log.info("partRejected " + order);
        String rejectFile = path.replace(".ord", ".rej");
        try {
            FileWriter fstream = new FileWriter(rejectFile, true);
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(order.toString() + "\n");
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void orderRejected() {
        log.info("orderRejected");
        try {
            String rejectFile = path.replace(".ord", ".rej");
            FileUtils.copyFile(new File(path), new File(rejectFile));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void getCustomerState() {
        Pattern p = Pattern.compile("[C]\\d+");
        Matcher m = p.matcher(path);
        String res = null;
        if (m.find()) {
            res = m.group();
        }
        res = res.replace("C", "");
        customer = ListofCustomersnSuppliers.getCustomers().get((int) (Integer.valueOf(res) - 1));
    }

    private void findTheSameOrders() {
        List<Order> newOrders = new ArrayList<Order>();
        for (int i = 0; i < orders.size(); i++) {
            if (orders.get(i).getSuk() != 0) {
                int newPtc = orders.get(i).getPcs();
                for (int k = i + 1; k < orders.size(); k++) {
                    // Compare each orderItem in odrer list
                    boolean suknull = orders.get(i).getSuk() == 0;
                    boolean suk = orders.get(i).getSuk() == (orders.get(k).getSuk());
                    boolean mat = orders.get(i).getMaterial().equals(orders.get(k).getMaterial());
                    boolean deliv = orders.get(i).getDeliv().equals(orders.get(k).getDeliv());
                    if (!suknull && suk && mat && deliv) {
                        newPtc = newPtc + orders.get(k).getPcs();
                        orders.get(i).setPcs(newPtc);
                        orders.get(k).setSuk(0);
                    }
                }
                Order list = new Order(orders.get(i).getSuk(), orders.get(i).getPcs(), orders.get(i).getMaterial(), orders.get(i).getDeliv());
                newOrders.add(list);
            }
        }
        this.orders = newOrders;
    }
    
    private String getDate() {
        Date dNow = new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
        return ft.format(dNow);
    }

    private void remane(String id) {
        File oldfile = new File(path);
        path = path.replace(fileName + ".tmp", getDate() + "-" + id + ".ord");
        File newfile = new File(path);
        oldfile.renameTo(newfile);
    }

    public void run() {
        processing();
    }
}
